/*
 * jAutomation: Portable input Automation 
 * Copyright (C) 2012 Dominik Hensler.  
 * http://code.google.com/p/jautomation
 * 
 * This Program uses JNativeHook by Alexander Barker:
 * JNativeHook: Global keyboard and mouse hooking for Java.
 * Copyright (C) 2006-2012 Alexander Barker.  All Rights Received.
 * http://code.google.com/p/jnativehook/
 *
 * 
 * This file is part of JAutomation.

 * JAutomation is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * JAutomation is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with JAutomation.  If not, see <http://www.gnu.org/licenses/>.
 */
/**
 *
 * @author Dominik Hensler
 */
package org.jautomation.core;

import java.awt.Point;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jautomation.pdetect.IPixDetect;
import org.jautomation.pdetect.PInvoker;
import org.jautomation.pdetect.ScanReceiver;
import org.jautomation.pdetect.WorkerContext;
import org.jautomation.pdetect.scantypes.PixelFinder;
import org.jautomation.pdetect.scantypes.PixelMonitor;

public class PchangeThread extends Thread {

    
    private volatile boolean threadInterrupted;
    private WorkerContext workerContext=new WorkerContext();
    public static Map<String, IPixDetect> scans = new HashMap<>();
    private final Object _lock = new Object();
    private Automation _automation;

    PchangeThread(Automation automation) {
        this._automation=automation;
        this.threadInterrupted = true;
        this.createScans();
    }

    @Override
    public void run() {
        while (true) {
            try {
                while (threadInterrupted == true) {
                    try {
                        synchronized (_lock) {
                            _lock.wait();
                            System.out.println("pixel detector resuming");
                        }
                    } catch (InterruptedException ex) {                    
                        Thread.currentThread().interrupt();
                    }
                }
                process();
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                Logger.getLogger(PchangeThread.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private void process() {
        PInvoker pinvoker = new PInvoker();
        if (PchangeThread.scans.containsKey(String.valueOf(workerContext.getScanmode()))) {
            pinvoker.prepare(PchangeThread.scans.get(String.valueOf(workerContext.getScanmode())));
            pinvoker.invoke(workerContext);
        }
    }

    public boolean isThreadInterrupted() {
        return threadInterrupted;
    }

    public void resumeThread() {
        synchronized (_lock) {
            this.threadInterrupted = false;
            _lock.notify();
        }
    }

    public void haltThread() {
        synchronized (_lock) {
            this.threadInterrupted = true;
            _lock.notify();
        }
    }

    private void createScans() {
        ScanReceiver scanReceiver = new ScanReceiver(_automation);                
        PchangeThread.scans.put("1", new PixelMonitor(scanReceiver));        
        PchangeThread.scans.put("2", new PixelFinder(scanReceiver));
    }

    public void setScanMode(int scanmode) {
        synchronized (_lock) {
            this.workerContext.setScanmode(scanmode);
        }
    }

    void setContextSnapshot(String[] commandArray) {
        synchronized (_lock) {
            this.workerContext.setCommandArray(commandArray);
        }
    }

    void setFirstRun(boolean firstRun) {
        this.workerContext.setFirstRun(firstRun);
    }

    void setCurrentPoint(Point currentPosition) {
        synchronized(_lock){
            this.workerContext.setCoordP(currentPosition);
        }
    }

    void findPixel(double[] cieLabColor) {
        synchronized(_lock){
            this.workerContext.setColor(cieLabColor);
            this.workerContext.setScanmode(2);
        }
    }
}
